#include <windows.h>
#include <stdio.h>
#include <tchar.h>

#define FILE_PATH _T("test_file.txt")
#define FILE_SIZE 4096
#define MAP_SIZE 1024

int main()
{
        // 设置控制台代码页为UTF-8
    SetConsoleOutputCP(CP_UTF8);  // 65001是UTF-8的代码页
    HANDLE hFile;
    HANDLE hMapFile;
    LPVOID pMap;

    // 1. 创建并初始化测试文件
    hFile = CreateFile(
        FILE_PATH,                    // 文件名
        GENERIC_READ | GENERIC_WRITE, // 读写权限
        0,                            // 不共享
        NULL,                         // 默认安全属性
        CREATE_ALWAYS,                // 总是创建新文件
        FILE_ATTRIBUTE_NORMAL,        // 普通文件
        NULL);                        // 无模板文件

    if (hFile == INVALID_HANDLE_VALUE)
    {
        _tprintf(_T("无法创建文件，错误码: %d\n"), GetLastError());
        return 1;
    }

    // 设置文件大小
    if (!SetFilePointer(hFile, FILE_SIZE, NULL, FILE_BEGIN) || !SetEndOfFile(hFile))
    {
        _tprintf(_T("无法设置文件大小，错误码: %d\n"), GetLastError());
        CloseHandle(hFile);
        return 1;
    }

    // 2. 创建文件映射
    hMapFile = CreateFileMapping(
        hFile,          // 文件句柄
        NULL,           // 默认安全属性
        PAGE_READWRITE, // 读写权限
        0,              // 高32位文件大小
        MAP_SIZE,       // 低32位文件大小
        NULL);          // 映射对象名称

    if (hMapFile == NULL)
    {
        _tprintf(_T("无法创建文件映射，错误码: %d\n"), GetLastError());
        CloseHandle(hFile);
        return 1;
    }

    // 3. 映射文件视图到进程地址空间
    pMap = MapViewOfFile(
        hMapFile,            // 映射对象句柄
        FILE_MAP_ALL_ACCESS, // 读写权限
        0,                   // 高32位偏移量
        0,                   // 低32位偏移量
        MAP_SIZE);           // 映射字节数

    if (pMap == NULL)
    {
        _tprintf(_T("无法映射文件视图，错误码: %d\n"), GetLastError());
        CloseHandle(hMapFile);
        CloseHandle(hFile);
        return 1;
    }

    // 4. 通过映射写入数据
    _tprintf(_T("通过映射写入数据...\n"));

    _stprintf_s((LPTSTR)pMap, MAP_SIZE / sizeof(TCHAR), _T("Hello, memory-mapped file!"));

    // 5. 确保数据写入文件
    if (!FlushViewOfFile(pMap, MAP_SIZE))
    {
        _tprintf(_T("无法刷新视图，错误码: %d\n"), GetLastError());
    }

    // 6. 解除映射
    if (!UnmapViewOfFile(pMap))
    {
        _tprintf(_T("无法解除映射，错误码: %d\n"), GetLastError());
    }

    // 7. 关闭映射对象和文件
    CloseHandle(hMapFile);
    CloseHandle(hFile);

    // 8. 重新打开文件并通过映射读取数据
    hFile = CreateFile(
        FILE_PATH,             // 文件名
        GENERIC_READ,          // 只读权限
        0,                     // 不共享
        NULL,                  // 默认安全属性
        OPEN_EXISTING,         // 打开现有文件
        FILE_ATTRIBUTE_NORMAL, // 普通文件
        NULL);                 // 无模板文件

    if (hFile == INVALID_HANDLE_VALUE)
    {
        _tprintf(_T("无法打开文件，错误码: %d\n"), GetLastError());
        return 1;
    }

    // 创建文件映射
    hMapFile = CreateFileMapping(
        hFile,         // 文件句柄
        NULL,          // 默认安全属性
        PAGE_READONLY, // 只读权限
        0,             // 高32位文件大小
        MAP_SIZE,      // 低32位文件大小
        NULL);         // 映射对象名称

    if (hMapFile == NULL)
    {
        _tprintf(_T("无法创建文件映射，错误码: %d\n"), GetLastError());
        CloseHandle(hFile);
        return 1;
    }

    // 映射文件视图
    pMap = MapViewOfFile(
        hMapFile,      // 映射对象句柄
        FILE_MAP_READ, // 只读权限
        0,             // 高32位偏移量
        0,             // 低32位偏移量
        MAP_SIZE);     // 映射字节数

    if (pMap == NULL)
    {
        _tprintf(_T("无法映射文件视图，错误码: %d\n"), GetLastError());
        CloseHandle(hMapFile);
        CloseHandle(hFile);
        return 1;
    }

    // 通过映射读取数据
    _tprintf(_T("通过映射读取数据: %s\n"), (LPTSTR)pMap);

    // 9. 解除映射并关闭句柄
    UnmapViewOfFile(pMap);
    CloseHandle(hMapFile);
    CloseHandle(hFile);

    // 10. 清理测试文件
    // if (!DeleteFile(FILE_PATH))
    // {
    //     _tprintf(_T("无法删除文件，错误码: %d\n"), GetLastError());
    //     return 1;
    // }

    _tprintf(_T("文件映射测试完成\n"));
    return 0;
}
